package com.apestech.api.workflow.lib.app;

import com.alibaba.druid.pool.DruidDataSource;
import com.apestech.api.workflow.lib.FlowUtil;
import com.apestech.api.workflow.lib.element.FlowExecute;
import com.apestech.api.workflow.lib.element.FlowTask;
import com.apestech.api.workflow.lib.element.WorkProcessEngine;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.DBUtil;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;

import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 * 原生结点场景
 *
 * @author hup
 * @create 2018-07-21-14:37
 */
public class FlowApp extends FlowUtil{

    private WorkProcessEngine engine;
    private SqlSession session;
    private JSONObject input;

    public FlowApp(WorkProcessEngine engine, JSONObject input) throws Exception {
        this.engine=engine;
        this.session= DBUtil.getSession(this.engine.getDataSource());
        this.session.setConnection(this.engine.getConnection());
        this.input=input;
    }

    /**
     * 开启流程
     * @throws Exception
     */
    public String startProcess() throws Exception {
        String businessKey=input.getString("businessKey");
        String processDefinitionKey=input.getString("processDefinitionKey");
        if(processDefinitionKey==null){
            throw new Exception("流程类型要求必填！");
        }
        if(businessKey==null){
            throw new Exception("业务单号要求必填！");
        }
        FlowExecute exec=new FlowExecute(engine);
        ProcessInstance ins=exec.startProcess(processDefinitionKey,businessKey,input);
        return ins.getId();
    }

    /**
     * 给结点赋用户，如存在一个用户，也要求用ArrayList<String>来传入
     * @throws Exception
     */
    public void assignTaskToUser() throws Exception {
        ArrayList<String> userlist= (ArrayList<String>) input.get("userlist");
        if(userlist==null){
            throw new Exception("人员列表不允许为空！");
        }
        FlowTask flowTask=getFlowTask(engine, input);
        if(flowTask.getTask().isSuspended()){
            throw new Exception("该任务为挂起状态，不允许做赋用户操作！");
        }
        String state=flowTask.getState();
        if(!("noAssgin".equals(state) || ("assgin".equals(state)))){
            throw new Exception("当前结点状态不允许执行赋用户操作！");
        }
        FlowExecute exec=new FlowExecute(engine);
        exec.assignTaskToUser(flowTask.getTask().getId(), userlist);
        flowTask.setState("assgin");
    }

    /**
     * 用户签收
     * @throws Exception
     */
    public void claimUser() throws Exception {
        String userId=input.getString("userId");
        if(userId==null){
            throw new Exception("签收人编码不允许为空！");
        }
        FlowTask flowTask=getFlowTask(engine, input);
        if(flowTask.getTask().isSuspended()){
            throw new Exception("该任务为挂起状态，不允许做签收操作！");
        }
        String state=flowTask.getState();
        if(!"assgin".equals(state)){
            throw new Exception("仅有赋用户之后才能做签收！");
        }
        JSONObject taskMap=getTaskMap(engine, flowTask.getTask().getId(), input);
        FlowExecute exec=new FlowExecute(engine);
        exec.deleteTaskAllUser(flowTask.getTask().getId());
        exec.claimTask(flowTask.getTask().getId(), userId);
        engine.getTaskService().setVariables(flowTask.getTask().getId(), taskMap);
        flowTask.setState("claim");
    }

    /**
     * 任务执行
     * @throws Exception
     */
    public void processTask() throws Exception {
        FlowTask flowTask=getFlowTask(engine, input);
        if(flowTask.getTask().isSuspended()){
            throw new Exception("该任务为挂起状态，不允许做执行操作！");
        }
        String state=flowTask.getState();
        if(!"claim".equals(state)){
            throw new Exception("签收之后才可保存！");
        }
        if(!input.getString("loginUserId").equals(flowTask.getTask().getAssignee())){
            throw new Exception("当前结点发起人["+input.getString("loginUserId")+"]不是结点经办人["+flowTask.getTask().getAssignee()+"]，请重新发起！");
        }
        FlowExecute exec=new FlowExecute(engine);
        flowTask.setState("complete");
        if(input.get("oa_var")==null){
            exec.processTask(flowTask.getTask().getId(), new JSONObject());
        } else {
            exec.processTask(flowTask.getTask().getId(), input.getJSONObject("oa_var"));
        }

    }

    public Task stopProcess() throws Exception {
        String opinion=input.getString("opinion");
        if(opinion==null){
            throw new Exception("中止原因必须说明！");
        }
        FlowTask flowTask=getFlowTask(engine, input);
        if(flowTask.getTask().isSuspended()){
            throw new Exception("该任务为挂起状态，不允许做执行操作！");
        }
        FlowExecute exec=new FlowExecute(engine);
        exec.stopProcess(flowTask.getProcessInstanceId(), opinion);
        return flowTask.getTask();
    }

    public InputStream getProcessInstancePng()throws Exception{
        String processInstanceId=input.getString("processInstanceId");
        if(processInstanceId==null){
            throw new Exception("OA流程ID必填！");
        }
        FlowExecute exec=new FlowExecute(engine);
        return exec.getProcessInstancePng(processInstanceId);
    }



}
